#include "db/session.h"
#include "db/connection.h"

#include <wx/msgdlg.h>

wxString Session::tableName()
{
	return wxT("session");
}

wxDbTable * Session::defineColumns(
	wxDb * db,
	int & id, int & normID, int & dimensionID,
	int & rulebaseID, int & numberClusters, 
	double & mStart, double & mEnd, wxChar * name
)
{
	wxDbTable * table = new wxDbTable(db, Session::tableName(), 8, wxT(""), !wxDB_QUERY_ONLY, wxT(""));
	int i = 0;
	if (id != -1) {
		table->SetColDefs(i++, wxT("id"), DB_DATA_TYPE_INTEGER, &id,
			SQL_INTEGER, sizeof(id), true, true);
	}
		
	table->SetColDefs(i++, wxT("name"), DB_DATA_TYPE_VARCHAR, name,
        SQL_C_WXCHAR, sizeof(wxChar) * 255, true, true);
	table->SetColDefs(i++, wxT("norm_id"), DB_DATA_TYPE_INTEGER, &normID,
        SQL_INTEGER, sizeof(normID), true, true);
	table->SetColDefs(i++, wxT("dimension_id"), DB_DATA_TYPE_INTEGER, &dimensionID,
        SQL_INTEGER, sizeof(dimensionID), true, true);
	table->SetColDefs(i++, wxT("rulebase_id"), DB_DATA_TYPE_INTEGER, &rulebaseID,
        SQL_INTEGER, sizeof(rulebaseID), true, true);
	table->SetColDefs(i++, wxT("number_clusters"), DB_DATA_TYPE_INTEGER, &numberClusters,
		SQL_INTEGER, sizeof(numberClusters), true, true);
	table->SetColDefs(i++, wxT("m_start"), DB_DATA_TYPE_FLOAT, &mStart,
        SQL_DOUBLE, sizeof(mStart), true, true);
	table->SetColDefs(i++, wxT("m_end"), DB_DATA_TYPE_FLOAT, &mEnd,
        SQL_DOUBLE, sizeof(mEnd), true, true);
	return table;
}

vector<Session> Session::getFullList()
{
	wxDb * db = DbConnection::getInstance()->getPointer();
	int id = 0;
	int normID = 0;
	int dimensionID = 0;
	int rulebaseID = 0;
	int numberClusters = 0;
	double mStart = 0;
	double mEnd = 0;
	wxChar name[255];

	wxDbTable * table = Session::defineColumns(db, 
							id, normID, dimensionID,
							rulebaseID, numberClusters,
							mStart, mEnd, name);

	if (!table->Open()) {
		DbConnection::handleError(wxT("TABLE OPEN ERROR: "), table->GetDb());
	}
	if (!table->Query()) {
		DbConnection::handleError(wxT("QUERY ERROR: "), table->GetDb());
	}

	vector<Session> ret;
	while (table->GetNext()) {
		Session item;
		item.ID = id;
		item.name = name;
		item.normID = normID;
		item.dimensionID = dimensionID;
		item.rulebaseID = rulebaseID;
		item.numberClusters = numberClusters;
		item.mStart = mStart;
		item.mEnd = mEnd;
		ret.push_back(item);
	}

	return ret;
}

int Session::createRecord(const Session & record)
{
	wxChar name[255];
	int id = -1;
	int normID = record.normID;
	int dimensionID = record.dimensionID;
	int rulebaseID = record.rulebaseID;
	int numberClusters = record.numberClusters;
	double mStart = record.mStart;
	double mEnd = record.mEnd;
	wxStrcpy(name, record.name);

	wxDb * db = DbConnection::getInstance()->getPointer();
	wxDbTable * table = Session::defineColumns(db,
		id, normID, dimensionID, rulebaseID,
		numberClusters, mStart, mEnd, name);

	if (!table->Open()) {
		DbConnection::handleError(wxT("TABLE OPEN ERROR: "), table->GetDb());
	}

	if (!table->Insert()) {
		DbConnection::handleError(wxT("CREATING ERROR: "), table->GetDb());
		table->GetDb()->RollbackTrans();
		wxDELETE(table);
		return 0;
	}
	if (table->GetDb()->CommitTrans()) {
		int lastId = DbConnection::getInstance()->getLastInsertID(Session::tableName());
		wxDELETE(table);
		return lastId;
	}
	return 0;
}

bool Session::updateRecord(const Session & record)
{
	return false;
}

bool Session::deleteRecord(const Session & record)
{
	wxDb * db = DbConnection::getInstance()->getPointer();
	wxDbTable * table = new wxDbTable(db, Session::tableName(), 2, wxT(""), !wxDB_QUERY_ONLY, wxT(""));
	if (!table->DeleteWhere(wxT("id = ") + wxString::Format(wxT("%d"), record.ID))) {
		DbConnection::handleError(wxT("DELETION ERROR: "), table->GetDb());
		table->GetDb()->RollbackTrans();
		return false;
	}
	return table->GetDb()->CommitTrans();
}